﻿/// <reference path="../../lib/underscore.js" />
/// <reference path="../Structures/FolioFixer_DataTypes.js" />
/// <reference path="//Microsoft.WinJS.1.0/js/base.js" />

var IndexedDBManager = WinJS.Class.define(
    function (upgrade, error) {
        this._dbName = "db";
        this._dbVersion = 1;

        this._upgrade = function (evt) {
            db = evt.target.result;

            if (!(_.contains(db.objectStoreNames, "portfolios"))) {
                var portfolioStore = db.createObjectStore("portfolios", { keyPath: "id", autoIncrement: true });
                portfolioStore.add(new FolioFixer.DataTypes.PortfolioInfo("Big Four", new Date("1/1/2012 UTC"), ["MSFT", "AAPL", "GOOG", "FB"]));
            }
        }

        this._error = error || function (evt) { console.log(evt.message); };
    },
    {
        getPortfolio: function (id) {
            var that = this;
            return new WinJS.Promise(function (complete, error) {
                that.getPortfolios().then(function (portfolios) {
                    var p = _.find(portfolios, function (portfolio) { return portfolio.id == id; });
                    complete(p);
                });
            });
        },
        putPortfolio: function(portfolio) {
            var that = this;
            return that._putItem(portfolio, "portfolios");
        },
        getPortfolios: function () {
            return this._getItems("portfolios");
        },
        _putItem: function (item, objectStoreName) {
            var that = this;
            return new WinJS.Promise(function (complete) {
                that._getObjectStore("readwrite", objectStoreName).then(
                    function (store) {
                        var reqput = store.put(item);
                        reqput.onsuccess = function (req) {
                            complete(req.target.result);
                        }
                    }
                );
            });
        },
        _getItems: function (objectStoreName) {
            var that = this;
            return new WinJS.Promise(function (complete, error, progress) {
                that._getObjectStore("readonly", objectStoreName).then(
                    function (store) {
                        var items = [];
                        var req = store.openCursor();
                        req.onerror = that._error;
                        req.onsuccess = function (evt) {
                            var cursor = evt.target.result;

                            if (cursor) {
                                items.push(cursor.value);
                                cursor.continue();
                                return;
                            }
                            else {
                                complete(items);
                            }
                        }
                    }
                );
            });
        },
        _ensureDbOpen: function () {
            var that = this;

            if (that._cachedDb) {
                return WinJS.Promise.wrap(that._cachedDb);
            }

            return new WinJS.Promise(function (complete, error, progress) {
                var reqOpen = window.indexedDB.open(that._dbName, that._dbVersion);
                reqOpen.onerror = function (evt) {
                    error();
                };

                reqOpen.onupgradeneeded = function (evt) {
                    that._upgrade(evt);
                };

                reqOpen.onsuccess = function () {
                    that._cachedDb = reqOpen.result;
                    complete(that._cachedDb);
                };
            });
        },
        _getObjectStore: function (type, objectStoreName) {
            type = type || "readonly";
            var that = this;
            return new WinJS.Promise(function (complete, error) {
                that._ensureDbOpen().then(function (db) {
                    var transaction = db.transaction(objectStoreName, type);
                    complete(transaction.objectStore(objectStoreName));
                });
            });
        }
    }
);